/*
 * Copyright (c) 2022  by Junzhao
 * THIS FILE IS PART OF JAVASE Song Huongkang PROJECT
 * All Rights Reserved.
 */

package 比较器.Comparable接口;

import org.junit.Test;

import java.util.Arrays;

/**
 * @description 自然排序：java.lang.Comparable
 *
 * 正常情况下引用数据类型只能使用 == 或 !=
 * 开发场景中需要多个对象的排序 也就需要比较对象的“大小”
 *
 Comparable接口强行对实现它的每个类的对象进行整体排序。这种排序被称
    为类的自然排序。
 实现 Comparable 的类必须实现 compareTo(Object obj) 方法，两个对象即
    通过 compareTo(Object obj) 方法的返回值来比较大小。如果当前对象this大
    于形参对象obj，则返回正整数，如果当前对象this小于形参对象obj，则返回
    负整数，如果当前对象this等于形参对象obj，则返回零。
 实现Comparable接口的对象列表（和数组）可以通过 Collections.sort 或
    Arrays.sort进行自动排序。实现此接口的对象可以用作有序映射中的键或有
    序集合中的元素，无需指定比较器。
 对于类 C 的每一个 e1 和 e2 来说，当且仅当 e1.compareTo(e2) == 0 与
    e1.equals(e2) 具有相同的 boolean 值时，类 C 的自然排序才叫做与 equals
    一致。建议（虽然不是必需的）最好使自然排序与 equals 一致。
 * @author 俊昭
 * @date 2022/4/17
*/
public class ComparableTest {
    /**
     * @description 使用举例 API 中现有的
     * @author 俊昭
     * @date 2022/4/17
    */
    @Test
    public void t1(){
        // String 包装类 等实现了Comparable接口
        // 比较规则是按字典序比较两个字符串。比较基于字符串中每个字符的Unicode值。
        // 这个String对象所表示的字符序列与参数String所表示的字符序列按字典顺序进行比较。
        // 如果该String对象按字典顺序排在参数String之前，则结果为负整数。
        // 如果该String对象按字典顺序跟随参数String，则结果为正整数。如果字符串相等，则结果为零;
        // 当equals(Object)方法返回true时，compareTo返回0。
        String[] arr = new String[]{"aa","bb","gg","cc","zz","dd","oo"};
        Arrays.sort(arr);// 将其排序

        System.out.println(Arrays.toString(arr));// [aa, bb, cc, dd, gg, oo, zz]
    }
    /**
     * @description 使用举例 自定义类
     * @author 俊昭
     * @date 2022/4/17
     */
    @Test
    public void t2(){
        Goods[] arr =new Goods[5];
        arr[0] = new Goods("雷蛇",200);
        arr[1] = new Goods("惠普",190);
        arr[2] = new Goods("Lenovo",150);
        arr[3] = new Goods("Xiaomi",99);
        arr[4] = new Goods("Samsung",150);

        Arrays.sort(arr);

        System.out.println(Arrays.toString(arr));


    }
}
class Goods implements Comparable{
    private String name;
    private int price;

    public Goods( String name,int price) {
        this.price = price;
        this.name = name;
    }

    @Override
    public String toString() {
        return "Goods{" +
                "name='" + name + '\'' +
                ", price=" + price +
                '}';
    }

    /**
     * @description 指明商品排序方式 价格从低到高 价格相同的话再按照名字排序
     * @param o 一个商品对象
     * @return [java.lang.Object]
     * @author 俊昭
     * @date 2022/4/17
    */
    @Override
    public int compareTo(Object o) {
        if (o instanceof Goods){
            Goods goods = (Goods) o;
            if (this.price > goods.price) {
                return 1;
            }else if (this.price < goods.price){
                return -1;
            }else {
//                return 0;
                return this.name.compareTo(goods.name);
            }
//             return Integer.compare(this.price, goods.price); 等价的
        }
        throw new RuntimeException("错误的类型输入");
    }
}